package com.zhuangjie.mvc.helper;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * 项目特有的BigDecimal工具类
 * 只会保留固定的小数位
 */
public class BigDecimalHelper {
    /**
     * 保留的小数点位数
     */
    private static final int SCALE = 2;
    /**
     * 舍入模式
     */
    private static final RoundingMode roundingMode = RoundingMode.DOWN;


    public static class BigDecimalLongOperation {
        private BigDecimal result;

        public BigDecimalLongOperation(BigDecimal num1) {
            result = num1;
        }
        public BigDecimalLongOperation add(BigDecimal num2) {
            result = additionOperation(result, num2);
            return this;
        }

        public BigDecimalLongOperation subtract(BigDecimal num2) {
            result = subtractionOperation(result, num2);
            return this;
        }

        public BigDecimalLongOperation multi(BigDecimal num2) {
            result = multiplicationOperation(result, num2);
            return this;
        }

        public BigDecimalLongOperation div(BigDecimal num2) {
            result = division(result, num2);
            return this;
        }

        public BigDecimal getResult() {
            return result.setScale(SCALE, roundingMode);
        }

    }

    public static BigDecimalLongOperation longOperation(BigDecimal num1) {
        return new BigDecimalLongOperation(num1);
    }

    /**
     * 外面不能进行new操作只能进行调用其静态方法来使用
     */
    private BigDecimalHelper() {
    }

    /**
     * 创建零的BigDecimal
     *
     * @return {@link BigDecimal}
     */
    public static BigDecimal createZeroBigDecimal() {
        BigDecimal result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 修剪为需要的小数位
     *
     * @param bigDecimals 大小数
     * @return {@link BigDecimal}
     */
    public static BigDecimal trimDecimalPlaces(BigDecimal bigDecimals) {
        if (bigDecimals == null) return null;
        return bigDecimals.setScale(SCALE, roundingMode);
    }


    /**
     * 加法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行加法运算
     * 乘法过去，还是null,返回0
     *
     * @param bigDecimals
     * @return
     */
    public static BigDecimal additionOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null ? bigDecimal : result.add(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 减法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行减法运算
     * 乘法过去，还是null,返回0
     *
     * @param bigDecimals
     * @return
     */
    public static BigDecimal subtractionOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null ? bigDecimal : result.subtract(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 除法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行乘法运算
     * 乘法过去，还是null,返回0
     *
     * @param bigDecimals
     * @return
     */
    public static BigDecimal division(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null ? bigDecimal : result.divide(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }


    /**
     * 乘法运算,希望小数点保留指定位数
     * 以null作为初始值，遍历后面的元素，如果遇到null，则跳过，否则进行乘法运算
     * 乘法过去，还是null,返回0
     *
     * @param bigDecimals
     * @return
     */
    public static BigDecimal multiplicationOperation(BigDecimal... bigDecimals) {
        if (bigDecimals == null || bigDecimals.length == 0) {
            throw new IllegalArgumentException("Argument 'bigDecimals' cannot be null or empty.");
        }
        BigDecimal result = null;
        for (BigDecimal bigDecimal : bigDecimals) {
            if (bigDecimal != null) {
                result = result == null ? bigDecimal : result.multiply(bigDecimal);
            }
        }
        if (result == null) result = BigDecimal.ZERO;
        // 截取指定小数点位
        return result.setScale(SCALE, roundingMode);
    }

}
